package MTRequest;

import java.util.ArrayList;

import MTProxyServer.MTConstant;
import MTProxyServer.MessageCentre;

/**
 * This class provide a general method and interface to communicate with its peer.
 * @author King
 *
 */
public abstract class MTRequest {

	private MessageCentre mMSGCenter = null; //Using the MSGCenter to send msg to peer
	protected MTRequestDataSource mRequestDataSource = null;
	protected ArrayList< String > mReceivedFromPeerRawData = new ArrayList< String >();
	protected ArrayList< String > mSendingToPeerRawData = new ArrayList< String >();
	protected int mRequestState = MTConstant.MT_REQ_NO_READY;
	

	/**
	 * Constructor
	 * @param aMSGCenter 
	 */
	public MTRequest( MessageCentre aMSGCenter )
	{
		mMSGCenter = aMSGCenter;
		LoadRequest();
	}
	
	/**
	 * Get the current request state
	 * @return
	 */
	public int GetRequestState()
	{
		return mRequestState;
	}
	
	/**
	 * Send MSG to peer
	 * @param aMSG Msg Content to peer
	 */
	protected void SendMSG( String aMSG )
	{
		mMSGCenter.SendMSG( aMSG );
	}
	
	/**
	 * Call it when the request is finished.
	 */
	protected void Finish()
	{
		mMSGCenter.FinishRequest();
	}
	
	/**
	 * Set the data source
	 * @param aRequestDataSource
	 */
	public void SetRequestDataSource( MTRequestDataSource aRequestDataSource )
	{
		mRequestDataSource = aRequestDataSource;
	}
	
	/**
	 * If a temp file store something, Load the temp file to restore the request
	 */
	private void LoadRequest()
	{
		// Handle Disconnect Use
	}
	
	/**
	 * When the request is interrupted, the current information is stored in a temp file
	 */
	protected void SaveRequest()
	{
		
	}
	
	/**
	 * Don't override this method. The method analysis the received Msg to get the peer
	 * request state and raw data
	 * @param aMSG Msg received from a peer
	 */
	public void ProcessMSG(String aMSG) 
	{
		String [] rawData = aMSG.split( "" + MTConstant.MT_REQ_ITEM_SEPARATER );
		int peerRequestState = Integer.valueOf( rawData[1] ); 
		
		if( MTConstant.MT_REQ_FINISH == peerRequestState ){
			this.Finish();
		}
		else{
			ProcessReqest( peerRequestState, rawData[2] );
			UpdateRequestState( peerRequestState );
			SendRequest();
		}
	}
	
	/**
	 * Update the request State
	 * @param aPeerState
	 */
	abstract protected void UpdateRequestState( int aPeerState );
	
	/**
	 * Process the peer's raw data to provide the relative service
	 * @param aPeerState
	 * @param peerRawData
	 */
	abstract protected void ProcessReqest( int aPeerState, String peerRawData );
	
	/**
	 * Send request or reply to peer
	 */
	abstract public void SendRequest();
}
